/*
 * Copyright (c) 2010 Nokia Corporation.
 */

#include "mainwindow.h"
#include "imageloader.h"
#include "imagewidget.h"
#include "keyeventlistener.h"
#include "myqtengine.h"

#include <QDebug>
#include <QDeclarativeItem>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setWindowTitle("QMultiWinEx");

#ifdef Q_WS_MAEMO_5
    window()->setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
#endif

    m_internalState = ENoState;
    m_messageBox = 0;

    // Class for loading images
    m_imageLoader = new ImageLoader(this);

    // QML main window
    m_qmlView = new QDeclarativeView(this);
    m_qmlView->setResizeMode(QDeclarativeView::SizeRootObjectToView);

    // Create Qt engine for the QML
    m_myQtEngine = new MyQtEngine(this);

    // Set picture model into QML
    m_qmlView->rootContext()->setContextProperty("pictureModel", QVariant::fromValue(m_myQtEngine->picturePaths()));

    // Set engine visible to QML
    m_qmlView->rootContext()->setContextProperty("MyQtEngine", m_myQtEngine);

    // Set QML source
    m_qmlView->setSource(QUrl("qrc:/Main.qml"));

    // Listen showImage signal from QML
    QObject *rootObject = dynamic_cast<QObject*>(m_qmlView->rootObject());
    QObject::connect(rootObject, SIGNAL(showImage(QVariant)), this, SLOT(showImage(QVariant)));

    // Get GridView pointer from QML
    QObject* root = m_qmlView->rootObject();
    m_qml_gridView = root->findChild<QObject*>("gridView");


    // Filter used in all platforms
    m_keyEventListener = new KeyEventListener(this);
    QObject::connect(m_keyEventListener,SIGNAL(keyboardEnabled()),this,SLOT(keyboardEnabled()));
    QObject::connect(m_keyEventListener,SIGNAL(keyboardDisabled()),this,SLOT(keyboardDisabled()));
    qApp->installEventFilter(m_keyEventListener);

    // Show focus always on Symbian 3rd platforms
#ifdef Q_OS_SYMBIAN
    if (QSysInfo::s60Version() <= QSysInfo::SV_S60_3_2) {
        m_qml_gridView->setProperty("focusOnWidth",QVariant(12));
        m_qml_gridView->setProperty("focusOffWidth",QVariant(12));
        m_qml_gridView->setProperty("removeFocus",QVariant(false));
    }
#endif

    // Symbian and Maemo -----------------------------------------------------
    //
#if defined Q_OS_SYMBIAN || defined Q_WS_MAEMO_5 || defined Q_WS_SIMULATOR

    // Create menu
#if defined Q_OS_SYMBIAN || defined Q_WS_SIMULATOR
    m_openAction = menuBar()->addAction("Open",this,SLOT(openCurrentItem()));
    m_deleteAction = menuBar()->addAction("Delete",this,SLOT(deleteCurrentItem()));
    m_openAction->setEnabled(false);
    m_deleteAction->setEnabled(false);
    menuBar()->addAction("Exit",QApplication::instance(),SLOT(quit()));
#endif

#ifdef Q_WS_MAEMO_5
    // For support Maemo StackedWindow
    setAttribute(Qt::WA_Maemo5StackedWindow);
#endif

    setCentralWidget(m_qmlView);

    // Remove context menu from the all widgets
    QWidgetList widgets = QApplication::allWidgets();
    QWidget* w = 0;
    foreach(w,widgets){
        w->setContextMenuPolicy(Qt::NoContextMenu);
    }

#elif defined Q_WS_WIN
    // Windows ---------------------------------------------------------------
    //

    // Set how focus in shown in QML
    //m_qml_gridView->setProperty("focusOnWidth",QVariant(12));
    //m_qml_gridView->setProperty("focusOffWidth",QVariant(12));
    //m_qml_gridView->setProperty("removeFocus",QVariant(false));

    // Create Window MDI
    m_mdiArea = new QMdiArea(this);

    // Create menu
    QMenu* menu = menuBar()->addMenu("File");
    menu->addAction("Open",this,SLOT(openCurrentItem()));
    menu->addAction("Delete",this,SLOT(deleteCurrentItem()));
    menu->addAction("Exit",QApplication::instance(),SLOT(quit()));

    // Create first main subwindow that has list of images
    m_mainMdi = new QMdiSubWindow;
    m_mainMdi->setWidget(m_qmlView);
    m_mainMdi->setAttribute(Qt::WA_DeleteOnClose);
    m_mainMdi->setMinimumSize(QSize(360,640));
    m_mdiArea->addSubWindow(m_mainMdi);

    setCentralWidget(m_mdiArea);
#endif
}

MainWindow::~MainWindow()
{
}

void MainWindow::showImage(QVariant path)
{
    m_selectedImage = path.toString();
    QTimer::singleShot(400,this,SLOT(doShowImage()));
}

void MainWindow::doShowImage()
{
    // Load selected image and create new window where to show it

    // Calculate image size
    QSize imageSize;
#if defined Q_OS_SYMBIAN || defined Q_WS_MAEMO_5 || defined Q_WS_SIMULATOR
    imageSize = size();
#elif defined Q_WS_WIN
    imageSize = QSize(size().width()/2,size().height()/2);
#endif

    // Load selected image from the list
//    QPixmap pixmap = m_imageLoader->loadImage(m_selectedImage,imageSize);

#if defined Q_OS_SYMBIAN || defined Q_WS_MAEMO_5 || defined Q_WS_SIMULATOR
    // Create next window for Symbian and Maemo
    openNewWindow(m_selectedImage);
#elif defined Q_WS_WIN
    // Create next window for Windows
    openNewWindowWin32(m_selectedImage);
#endif

}

void MainWindow::openNewWindowWin32(QString path)
{
    // Create new MDI window for Windows
#ifdef Q_WS_WIN
    // New MDI window
    QMdiSubWindow* newMdi = new QMdiSubWindow;

    // Set image name as new window title
    newMdi->setWindowTitle(m_imageLoader->imageName(path));

    // Image content for the child window
    ImageWidget* imageWidget = new ImageWidget(path);
    newMdi->setWidget(imageWidget);
    newMdi->setAttribute(Qt::WA_DeleteOnClose);

    // Add new window
    m_mdiArea->addSubWindow(newMdi);

    // Set size and show
    newMdi->setMinimumSize(QSize(size().width()/2,size().height()/2));
    newMdi->show();
    m_mainMdi->setFocus(Qt::ActiveWindowFocusReason);
#endif
}

void MainWindow::openNewWindow(QString path)
{
    // Create new window for Symbian and Maemo

    // Maemo : Check that there is at maximum two widget with WA_Maemo5StackedWindow attribute
    // These two are main window and one child. Maemo "back arrow" functionality supports only one child
#if defined Q_WS_MAEMO_5
    QWidgetList widgets = QApplication::allWidgets();
    QWidget* w = 0;
    int childCount = 0;
    foreach(w,widgets){
        if (w->testAttribute(Qt::WA_Maemo5StackedWindow)) {
            childCount++;
        }
    }
    if (childCount>1)
        return;
#endif

    // Symbian: Check is there already child open, application supports only
    // one QMainWindow child in the same time
#if defined Q_OS_SYMBIAN || defined Q_WS_SIMULATOR
    QWidgetList widgets = QApplication::allWidgets();
    QWidget* w = 0;
    int mainWindowCount=0;
    foreach(w,widgets){
        // NOTE: that QMainWindow is our child window class name.
        // Application main QMainWindow name is MainWindow
        if (w->metaObject()->className() == QMainWindow::staticMetaObject.className()) {
            mainWindowCount++;
        }
    }
    if (mainWindowCount>0)
        return;
#endif

    QMainWindow* nextWindow = 0;
#ifdef Q_WS_MAEMO_5
    nextWindow = new QMainWindow(this); // NOTE: this in Maemo for support StackedWindow
    nextWindow->setAttribute(Qt::WA_Maemo5StackedWindow);
    nextWindow->setAttribute(Qt::WA_DeleteOnClose);
#elif defined Q_OS_SYMBIAN || defined Q_WS_SIMULATOR
    nextWindow = new QMainWindow; // NOTE: no parent in Symbian
    nextWindow->setAttribute(Qt::WA_DeleteOnClose);
#endif

    // Set image name as new window title
    nextWindow->setWindowTitle(m_imageLoader->imageName(path));

    // Image content for the child window
    ImageWidget* imageWidget = new ImageWidget(path,nextWindow);
    nextWindow->setCentralWidget(imageWidget);

    // Create menu
    nextWindow->menuBar()->addAction("Exit",QApplication::instance(),SLOT(quit()));

    // Create Back CBA
    QAction *backSoftKeyAction = new QAction(QString("Back"), this);
    backSoftKeyAction->setSoftKeyRole(QAction::NegativeSoftKey);
    // Back button closes the window
    QObject::connect(backSoftKeyAction, SIGNAL(triggered()),
    nextWindow, SLOT(close()));
    nextWindow->addAction(backSoftKeyAction);

    // Show
    nextWindow->showMaximized();
}

void MainWindow::printObjectTree(QObject* parent)
{
    if (parent) {
        qDebug() << "className:" << parent->metaObject()->className();
        qDebug() << "objectName:" << parent->objectName();

        QObjectList list = parent->children();
        QObject* item;
        foreach(item,list) {
            if (item->children().count()>0) {
                qDebug() << "--Childrens found--";
                printObjectTree(item);
            } else {
                qDebug() << "className:" << parent->metaObject()->className();
                qDebug() << "objectName:" << parent->objectName();
            }
        }
    }
}

void MainWindow::openCurrentItem()
{
    // Get current image from QML
    if (m_qml_gridView) {
        QVariant value = m_qml_gridView->property("currentIndex");
        m_selectedImage = m_myQtEngine->pictureAt(value).toString();
        doShowImage();
    }
}

void MainWindow::deleteCurrentItem()
{
    if (!m_messageBox) {

        // Get current image from QML
        if (m_qml_gridView) {
            QVariant value = m_qml_gridView->property("currentIndex");
            m_selectedImage = m_myQtEngine->pictureAt(value).toString();
        }

        // Show message
        m_messageBox = new QMessageBox(this);
        QString fileName = m_imageLoader->imageName(m_selectedImage);

        int ret = m_messageBox->question(this, "QMultiWinEx", QString("Delete %1 ?").arg(fileName), QMessageBox::Yes
            | QMessageBox::No);

        delete m_messageBox;
        m_messageBox = 0;
        if (ret == QMessageBox::Yes) {

            // Delete from file
            QFile::remove(m_selectedImage);

            // Delete image from QML model
            m_myQtEngine->removeImage(m_selectedImage);
            m_qmlView->rootContext()->setContextProperty("pictureModel", QVariant::fromValue(m_myQtEngine->picturePaths()));
        }
    }
}

void MainWindow::touchEnabled(bool enable)
{
    if (enable && (m_internalState == EKeyboardEnabled || m_internalState == ENoState)) {
        // Disable some additional features for the keyboard device

#ifdef Q_OS_SYMBIAN
        m_openAction->setEnabled(false);
        m_deleteAction->setEnabled(false);
#endif
        // Set how focus in shown in QML
        m_qml_gridView->setProperty("focusOnWidth",QVariant(12));
        m_qml_gridView->setProperty("focusOffWidth",QVariant(4));
        m_qml_gridView->setProperty("removeFocus",QVariant(true));

        // New state
        m_internalState = ETouchEnabled;
    } else if(!enable && (m_internalState == ETouchEnabled || m_internalState == ENoState)) {
        // Enable some additional features for the keyboard device

#ifdef Q_OS_SYMBIAN
        m_openAction->setEnabled(true);
        m_deleteAction->setEnabled(true);
#endif

        // Set how focus in shown in QML
        m_qml_gridView->setProperty("focusOnWidth",QVariant(12));
        m_qml_gridView->setProperty("focusOffWidth",QVariant(12));
        m_qml_gridView->setProperty("removeFocus",QVariant(false));

        // New state
        m_internalState = EKeyboardEnabled;
    }
}

void MainWindow::keyboardEnabled()
{
    touchEnabled(false);
}

void MainWindow::keyboardDisabled()
{
    touchEnabled(true);
}

